#
# CIDOC Conceptual Reference Models
# <http://cidoc.ics.forth.gr/docs/cidoc_crm_version_5.0.1_Mar09.pdf>
#
# This collection of models and properties use the CIDOC CRM ontology to
# enrich the FRBR base models and to provide interoperability with other
# CIDOC systems.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright 2009,2010- Jeremy Nelson, Tomichi Informatics LLC

import datetime,os
import MODSData

from google.appengine.ext import db
from google.appengine.api import users

#=============================================================================#
# Models                                                                      #
#=============================================================================#
class CRM_Entity(MODSData.BaseModel):
    """ Comprises all things in the universe of discourse of the
        CIDOC Conceptual Reference Model.

        Code: E1

        """
    code = "E1"
    identifiers = db.ListProperty(db.Key,default=None)
    is_type = db.ReferenceProperty(MODSData.BaseModel)
    note = db.TextProperty()
    preferred_identifier = db.ReferenceProperty(MODSData.identifier)
    exemplifies = db.ReferenceProperty(MODSData.BaseModel)

class TemporalEntity(CRM_Entity):
    """ Comprises all phenomena, such as the instances of E4 Periods,
        E5 Events and states, which happen over a limited extent in time.
    """
    code = "E2"
    time_span = db.ListProperty(MODSData.BaseDateProperty,
                                default=None)
    equal_in_time = db.SelfReferenceProperty()
    finished_by = MODSData.BaseDateProperty()
    started_by = db.SelfReferenceProperty()
    occurs_during = db.SelfReferenceProperty()
    overlaps_with = db.SelfReferenceProperty()
    meets_with = db.SelfReferenceProperty()
    occurs_before = db.SelfReferenceProperty()

class ConditionState(TemporalEntity):
    """ Comprises the states of objects characterised by a certain condition
         over a time-span. """
    code = "E3"
    state = db.StringProperty()
    consists_of = db.SelfReferenceProperty()

class Period(TemporalEntity):
    """ Comprises sets of coherent phenomena or cultural manifestations
        bounded in time and space. """
    code = "E4"
    witnessed_at = MODSData.hierarchicalGeographic()
    witnessed_on = db.ReferenceProperty()
    part_of = db.SelfReferenceProperty()
    falls_within = db.SelfReferenceProperty()
    overlaps_with = db.SelfReferenceProperty()
    separated_from = db.SelfReferenceProperty()

class Event(Period):
    """ Comprises changes of states in cultural, social or physical systems,
        regardless of scale, brought about by a series or group of coherent
        physical, cultural, technological or legal phenomena. Such changes of
        state will affect instances of E77 Persistent Item or its subclasses.
    """
    code = "E5"
    participants = db.ListProperty(db.Key,
                                   default=None)
    occurred_with_items = db.ListProperty(db.Key,
                                          default=None)

class Destruction(Event):
    """ Class comprises events that destroy one or more instances of E18
        Physical Thing such that they lose their identity as the subjects
        of documentation."""
    code= "E6"
    destroyed_by = db.ListProperty(db.Key,
                                   default=None)

class Activity(Event):
    """ Comprises actions intentionally carried out by instances of E39
        Actor that result in changes of state in the cultural, social,
        or physical systems documented."""
    code = "E7"
    performed_by = db.ListProperty(db.Key,
                                   default=None)
    influenced_by = db.ListProperty(db.Key,
                                    default=None)
    used_specific_object = db.ListProperty(db.Key,
                                           default=None)
    motivated_by = db.ListProperty(db.Key,
                                   default=None)
    intended_use_of = db.ListProperty(db.Key,
                                      default=None)
    specific_purpose = db.ReferenceProperty(Event)
    general_purpose = db.ListProperty(db.Key,
                                      default=None)
    general_techniques = db.ListProperty(db.Key,
                                         default=None)
    specific_techniques = db.ListProperty(db.Key,
                                          default=None)
    used_object_of_type = db.ListProperty(db.Key,
                                          default=None)
    continued_by = db.SelfReferenceProperty()

class Acquisition(Activity):
    """ Transfers of legal ownership from one or more instances of
        E39 Actor to one or more other instances of E39 Actor. """
    code = "E8"
    transferred_ownership_to = db.ListProperty(db.Key,
                                               default=None)
    transferred_ownership_from = db.ListProperty(db.Key,
                                                 default=None)
    transfered_title_of = db.ListProperty(db.Key,
                                          default=None)

class Move(Activity):
    """ Changes of the physical location of the instances of E19
        Physical Object. """
    code = "E9"
    moved = db.ListProperty(db.Key,
                            default=None)
    moved_to = MODSData.hierarchicalGeographic()
    moved_from = MODSData.hierarchicalGeographic()

class TransferofCustody(Activity):
    """ Transfers of physical custody of objects between instances of E39
        Actor. """
    code = "E10"
    custody_surrendered_by = db.ListProperty(db.Key,
                                             default=None)
    custody_received_by = db.ListProperty(db.Key,
                                          default=None)
    transferred_custody_by = db.ListProperty(db.Key,
                                             default=None)

class Modification(Activity):
    """ All instances of E7 Activity that create, alter or change E24
        Physical Man-Made Thing. """
    code = "E11"
    modified_by = db.ListProperty(db.Key,
                                  default=None)
    employed_in = db.ListProperty(db.Key,
                                  default=None)

class Production(Modification):
    """ Activities that are designed to, and succeed in, creating one or
        more new items. """
    code = "E12"
    produced_by = db.ListProperty(db.Key,
                                  default=None)

class AttributeAssignment(Activity):
    """ Actions of making assertions about properties of an object or any
        relation between two items or concepts. """
    code = "E13"
    attributed_by = db.ListProperty(db.Key,
                                    default=None)
    assigned_by = db.ListProperty(db.Key,
                                  default=None)

class ConditionAssessment(AttributeAssignment):
    """ Describes the act of assessing the state of preservation of an object
        during a particular period."""
    code = "E14"
    assessed_by = db.ListProperty(db.Key,
                                  default=None)
    identified_by = db.ListProperyt(db.Key,
                                    default=None)

class IdentifierAssignment(AttributeAssignment):
    """ Activities that result in the allocation of an identifier to an
        instance of E1 CRM Entity """
    code = "E15"
    assigned_identifier = db.ReferenceProperty()
    deassigned_identifier = db.ReferenceProperty()
    used_constituent = db.ListProperty(db.Key,
                                       default=None)

class Measurement(AttributeAssignment):
    """ Measuring physical properties and other values that can be
        determined by a systematic procedure. """
    code = "E16"
    measured_by = db.ListProperty(db.Key,
                                  default=None)
    observed_dimension = db.ListPropery(db.Key,
                                        default=None)
    
class TypeAssignment(AttributeAssignment):
    """ The actions of classifying items of whatever kind. Such items
        include objects, specimens, people, actions and concepts. """
    code = "E17"
    classified = db.ListProperty(db.Key,
                                 default=None)
    assigned_by = db.ListProperty(db.Key,
                                  default=None)

class PhysicalThing(CRM_Entity):
    """ All persistent physical items with a relatively stable form,
        man-made or natural."""
    code = "E18"
    condition_of = db.ReferenceProperty(ConditionState)
    consists_of = db.ListProperty(db.Key,
                                  default=None)
    composed_of = db.SelfReferenceProperty()
    has_former_or_current_keeper = db.BooleanProperty()
    current_keeper = db.ListProperty(db.Key,
                                     default=None)
    has_former_or_current_owner = db.BooelanProperty()
    current_owner = db.ListProperty(db.Key,
                                    default=None)
    former_location = MODSData.hierarchicalGeographic()
    current_location = MODSData.hierarchicalGeographic()
    section_definition = db.ListProperty(db.Key,
                                         default=None)
    section = MODSData.hierarchicalGeographic()

class PhysicalObject(PhysicalThing):
    """ Items of a material nature that are units for documentation
        and have physical boundaries that separate them completely in an
        objective way from other objects. """
    code = "E19"
    permanent_location = MODSData.hierarchicalGeographic()
    current_location = MODSData.hierarchicalGeographic()
    has_features = db.ListProperty(db.Key,
                                   default=None)
    number_of_parts = db.IntegerProperty()

class PhysicalManMadeObject(PhysicalThing):
    """ All persistent physical items that are purposely created by human
        activity."""
    code = "E24"
    depicted_by = db.ListProperty(db.Key,
                                  default=None)
    shows_visual_items = db.ListProperty(db.Key,
                                         default=None)
    carried_by = db.ListProperty(db.Key,
                                 default=None)

##class ManMadeFeature(PhysicalManMadeObject,):
##    """ 
class InformationObject(CRM_Entity):
    ''' InformationObject are texts, multimedia objects, procedural
        prescriptions, computer program code, algorithm or mathematical
        formulae, that have an objectively recognizable structure and are
        documented as single units.'''
    code="E73"
  
class DesignOrProcedure(InformationObject):
    ''' Documented plans for the execution of actions in order to
        achieve a result of a specific quality, form or contents.'''
    code = "E29"
    associated_with = db.SelfReferenceProperty()
    foresees_use_of = db.ReferenceProperty(collection_name="material")
    

    

    
    
    
